package org.whale.tool;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.service.V;
import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.logging.Handler;
import java.util.stream.Stream;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.whale.entity.AppointmentOrder;
import org.whale.entity.DoctorScheduling;
import org.whale.service.AppointmentOrderService;
import org.whale.service.DoctorSchedulingService;


/**
 * AI Tools
 */
@Component
@Slf4j
public class DoctorTool {

    @Resource
    private AppointmentOrderService appointmentOrderService;

    @Resource
    private DoctorSchedulingService doctorSchedulingService;

    /**
     * 查询医生
     */
    @Tool(name = "根据科室推荐合适的医生",value = "根据科室查询该科室下的医生，并推荐一名医生")
    public String queryDoctorName(@P("科室")String dept){
        log.info("根据科室推荐合适的医生 {}",dept);
        List<DoctorScheduling> doctorSchedulings = doctorSchedulingService.list(new LambdaQueryWrapper<>(DoctorScheduling.class).eq(DoctorScheduling::getDept, dept));
        if(CollectionUtil.isEmpty(doctorSchedulings)){
            return "[]";
        }
        return JSONUtil.toJsonStr(doctorSchedulings);
    }

    /**
     * 查询订单
     */
    @Tool(name = "查询用户的所有挂号单",value = "根据用户的身份证查询所有挂号单,以友好的方式返回给用户，注意结果的可读性")
    public String queryOrder(@P("身份证")String idCard){
        log.info("查询用户的挂号单 {}",idCard);

        List<AppointmentOrder> appointmentOrders = appointmentOrderService.list(new LambdaQueryWrapper<>(AppointmentOrder.class).eq(AppointmentOrder::getIdCard,idCard));
        if(CollectionUtil.isEmpty(appointmentOrders)){
            return "没有查询到挂号单";
        }
        return JSONUtil.toJsonStr(appointmentOrders);
    }

    /**
     * 查询是否有号
     */
    @Tool(name = "查询是否可预约",value = "根据用户提供的挂号科室，日期，时间，医生名字查询号源并返回给用户，如果查到的号源为空提示用户没有号源")
    public String queryCanAppointmentOrder(
            @V("科室")String dept,
            @V("预约日期") String date,
            @V("预约时间") String time,
            @V("医生名字") String doctorName){

        log.info("查询是否可以预约 {} - {} - {} - {}",dept , date , time , doctorName);
        List<DoctorScheduling> doctorSchedulings = doctorSchedulingService.list(new LambdaQueryWrapper<>(DoctorScheduling.class)
                        .eq(ObjectUtil.isNotNull(date),DoctorScheduling::getDate,date)
                        .eq(ObjectUtil.isNotNull(doctorName),DoctorScheduling::getDoctorName,doctorName )
                        .eq(ObjectUtil.isNotNull(dept),DoctorScheduling::getDept, dept));

        if(CollectionUtil.isEmpty(doctorSchedulings)){
            return null;
        }

        List<DoctorScheduling> list = doctorSchedulings.stream().filter(d ->  d.inTime(time)).toList();

        if(CollectionUtil.isEmpty(list)){
            return null;
        }

        return JSONUtil.toJsonStr(list);

    }


    /**
     * 执行挂号
     */
    @Tool(name = "预约挂号",value = "根据用户提供的挂号信息，优先执行工具方法 queryCanAppointmentOrder 查询是否可以预约并告知用户，" +
            "如果可以预约需要让用户确认预约信息，确认后执行预约挂号并把挂号结果：科室，医生，时间，单号以友好的方式返回")
    public String doAppointmentOrder(AppointmentOrder appointmentOrder){
        log.info("预约挂号 {}",appointmentOrder);
        AppointmentOrder exist = appointmentOrderService.queryOrder(appointmentOrder);
        if(ObjectUtil.isNotNull(exist)){
            return "已经有挂号单了";
        }

        //保持预约单
        appointmentOrderService.saveAppointmentOrder(appointmentOrder);

        return JSONUtil.toJsonStr(appointmentOrder);
    }


    /**
     * 取消预约
     */
    @Tool(name = "取消挂号",value = "根据用户提供的挂号信息取消挂号，要求用户提供身份证号和挂号单")
    public String cancelAppointmentOrder(AppointmentOrder appointmentOrder){
        log.info("取消挂号 {}",appointmentOrder);

        if(ObjectUtil.isNull(appointmentOrder.getId())){
            return "请提供单号";
        }
        if(ObjectUtil.isNull(appointmentOrder.getIdCard())){
            return "请提供身份证";
        }

        AppointmentOrder exist = appointmentOrderService.getBaseMapper().selectOne(new LambdaQueryWrapper<AppointmentOrder>()
                .eq(AppointmentOrder::getId,appointmentOrder.getId())
                .eq(AppointmentOrder::getIdCard,appointmentOrder.getIdCard())
        );
        if(ObjectUtil.isNull(exist)){
            return "没有挂号单";
        }
        appointmentOrderService.removeById(exist.getId());
        return "成功取消挂号";
    }
}
